<template>
  <div v-show="sectionList.length" class="text-text-01 black:text-text-01-dark">
    <transition name="dir-slide-fade" mode="out-in">
      <!-- 最小化 -->
      <div
        v-if="miniDirectory"
        class="directory-container flex py-2 pl-2 pr-2 justify-center flex-col items-center border-base-card w-9 rounded-md after:rounded-md bg-background-01 black:bg-background-01-dark"
      >
        <el-icon
          @click="handleDirectoryDisplay(false)"
          class="!h-6 !w-6 rounded bg-background-04 black:bg-background-04-dark cursor-pointer !text-text-01 black:!text-text-01-dark hover:bg-background-07 hover:!text-text-04 black:hover:bg-background-07-dark black:hover:!text-text-04-dark"
          ><OpenDirectory
        /></el-icon>
      </div>
      <!-- 展开 -->
      <div
        class="directory-container flex py-2 pl-2 pr-2 justify-center flex-col items-center gap-2 border-base-card w-36 rounded-md after:rounded-md bg-background-01 black:bg-background-01-dark"
        v-else
        ref="directory"
      >
        <!-- 头 -->
        <div class="stock-info text-base flex justify-between items-center text-center w-full">
          <span class="text-xs font-semibold">分析大纲</span>
          <el-icon
            @click="handleDirectoryDisplay(true)"
            class="!h-6 !w-6 rounded bg-background-04 black:bg-background-04-dark cursor-pointer !text-text-01 black:!text-text-01-dark hover:bg-background-07 hover:!text-text-04 black:hover:bg-background-07-dark black:hover:!text-text-04-dark"
            ><CloseDirectory
          /></el-icon>
        </div>
        <!-- 导航列表 -->
        <div
          class="nav-list pt-2 flex flex-wrap flex-col w-full gap-1 relative select-none after:border-border-02 black:after:border-border-02-dark"
          ref="sectionListRef"
        >
          <div
            class="nav-item h-7 text-center cursor-pointer border-base flex justify-start items-center text-xs gap-2 rounded after:rounded bg-background-02 black:bg-background-02-dark hover:text-text-04 black:hover:text-text-04-dark"
            v-for="item in sectionList"
            :key="item.id"
            @click="selectSection(item)"
            :class="{ active: item.active }"
          >
            <el-icon
              class="!h-full !w-5 rounded-l cursor-grab bg-background-04 black:bg-background-04-dark"
            >
              <DragIcon />
            </el-icon>
            <span
              class="text-ellipsis overflow-hidden whitespace-nowrap flex-1 text-left pr-2"
              :class="{ 'text-text-04': item.active }"
            >
              {{ item.title }}
            </span>
          </div>
        </div>
      </div>
    </transition>
  </div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted, ref, type Ref, nextTick, computed, watch } from 'vue'
import { DragIcon, CloseDirectory, OpenDirectory } from '@/components/icons'
import Sortable, { type SortableEvent } from 'sortablejs'
import { usePanelStore } from '@/stores/panel'
import { getEventBus } from '@/common/services/chat-event-bus'
import type { Section } from '@/common/models/recommend-result'
import { updateSectionSort } from '../services/chat-api'
import { ElMessage } from 'element-plus'
import { ERRORTYPE } from '@/common/config/const'

const { sectionSortEventBus, sectionSelectEventBus } = getEventBus()

const panelStore = usePanelStore()

// 导航栏元素
const sectionListRef: any = ref(null)

// 目录元素
const directory = ref()

// 是否展示
const miniDirectory = ref(false)

// 当前页面模块
const currentSections = computed(() => panelStore.currentSections)

// 原始导航列表数据 mock
const sectionList: Ref<Section[]> = ref([])

// 存储操作后列表
const localSectionList: Ref<Section[]> = ref([])

// 拖拽容器实例
let sorttableVm: Ref<Sortable | null> = ref(null)

onMounted(() => {
  setDragTabVm()
  setStatusByWindowWidth()
  window.addEventListener('resize', setStatusByWindowWidth)
})

onUnmounted(() => {
  window.removeEventListener('resize', setStatusByWindowWidth)
})

// 交互：根据窗口宽度设置目录显示状态
function setStatusByWindowWidth() {
  if (window.innerWidth < 1560) {
    miniDirectory.value = true
  }
}

// 交互：数组数据重排
function moveArrayElement<T>(array: T[], from: number, to: number): T[] {
  if (to >= 0 && to < array.length) {
    array.splice(to, 0, array.splice(from, 1)[0])
  }
  return array
}

// 交互：创建拖拽实例
function setDragTabVm() {
  sorttableVm.value = new Sortable(sectionListRef.value, {
    ghostClass: 'nav-ghost',
    chosenClass: 'nav-chosen',
    dragClass: 'nav-drag',
    forceFallback: true,
    animation: 250,
    onEnd: async function (evt: SortableEvent) {
      const { oldIndex, newIndex } = evt
      moveArrayElement(localSectionList.value, oldIndex || 0, newIndex || 0)
      console.log('排序后的数据', localSectionList.value)
      sectionSortEventBus.emit({ newIndex, oldIndex })
      const sids = localSectionList.value.map((section) => section.id)
      try {
        await updateSectionSort(panelStore.currentPanel!.id, sids)
      } catch (error) {
        window.f10log(ERRORTYPE.AJAX, `目录排序失败：${error}`, error)
        ElMessage.error('操作失败！')
      }
    },
    onStart: function (evt: SortableEvent) {
      window.weblog.report({
        id: 'thspc_f10_copilot_dir_drag',
        action: 'press',
        logmap: {}
      })
      const { oldIndex } = evt
      const item = localSectionList.value[oldIndex || 0]
      selectSection(item)
    }
  })
}

// 交互：选择模块
function selectSection(item: Section) {
  sectionList.value.map((nav) => {
    nav.active = nav.id === item.id
  })
  const selectSectionInfo = panelStore.getSectionInfo(item.id)
  selectSectionInfo?.cardVm?.selectSection(item)
  selectSectionInfo?.cardVm?.$el.scrollIntoView({
    behavior: 'smooth',
    block: 'center',
    inline: 'center'
  })
}

sectionSelectEventBus.on(({ section }) => {
  sectionList.value.map((nav) => {
    nav.active = nav.id === section.id
  })
})

// 交互：目录显隐处理
function handleDirectoryDisplay(show: boolean) {
  panelStore.setSections(Array.from(localSectionList.value))
  miniDirectory.value = show
  nextTick(() => {
    if (!show) {
      sorttableVm.value?.destroy()
      // 动画渲染后再实例化 动画500ms
      setTimeout(() => {
        setDragTabVm()
      }, 500)
    }
  })
}

watch(
  currentSections,
  () => {
    sectionList.value = currentSections.value.map((section) => {
      return {
        ...section,
        active: false,
        hover: false
      }
    })
    localSectionList.value = Array.from(sectionList.value)
  },
  { deep: true }
)
</script>

<style lang="less" scoped>
.nav-item {
  width: 100%;
  &.nav-drag {
    color: #636fff;
    opacity: 1 !important;
    border-radius: 4px;
    &::after {
      border-color: rgba(99, 111, 255, 1);
      border-radius: 4px;
    }
  }
  &.nav-ghost {
    opacity: 0.5;
    color: #636fff;
    border-radius: 4px;
    &::after {
      border-color: rgba(99, 111, 255, 1);
      border-radius: 4px;
    }
  }
  &.active {
    .el-icon {
      color: #636fff;
      background-color: #d8dbff;
    }
    &::after {
      border-color: rgba(99, 111, 255, 1);
    }
  }
}
.dark {
  .nav-item {
    &.active {
      .el-icon {
        color: #7e8dff;
        background-color: rgba(99, 111, 255, 0.4);
      }
      &::after {
        border-color: #7e8dff;
      }
    }
  }
}
.nav-list::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 200%;
  height: 200%;
  border-top-width: 1px;
  border-top-style: dashed;
  transform: scale(0.5);
  transform-origin: 0 0;
  pointer-events: none;
}
.dir-slide-fade-enter-active {
  transition: all 0.4s ease-out;
}

.dir-slide-fade-leave-active {
  transition: all 0.4s cubic-bezier(1, 0.5, 0.8, 1);
}

.dir-slide-fade-enter-from,
.dir-slide-fade-leave-to {
  transform: translateX(-100px);
  opacity: 0;
}
</style>
